//! # 宏测试 1
//!
//! 自动生成表头，自动写入数据
//!

use umya_spreadsheet::Worksheet;
use xlsx_group_write::prelude::*;

// # 示例 1 : 自动生成表头，各行数据自动写入

#[derive(XlsxGroupWriteQuicker)]
#[xlsx_group_write(
    line_writer_simple = "line_index-1:number,&self.name,&self.tel,&self.dep",
    group_maker = "&self.dep",
    template_simple = "序号,姓名,手机,部门",
    output_file_name_simple = "/tmp/test"
)]
struct MySimpleData {
    pub name: String,
    pub tel: String,
    pub dep: String,
}
impl MySimpleData {
    pub fn new(name: &str, tel: &str, dep: &str) -> Self {
        Self {
            name: name.into(),
            tel: tel.into(),
            dep: dep.into(),
        }
    }
}

#[test]
fn test_simple() {
    // 初始化待导出数据
    let data = vec![
        MySimpleData::new("张三", "185xxxx2228", "网金部"),
        MySimpleData::new("李四", "185xxxx2229", "运管部"),
        MySimpleData::new("王二", "185xxxx2230", "网金部"),
    ];
    // 导出数据到xlsx文件
    // 自动按照部门分别导出,同时还汇总导出一个汇总xlsx文件
    // 成功导出返回对应的文件信息和分组id
    let resp = MySimpleData::write2xlsx_all(&data);
    println!("resp:{resp:#?}");
}

// # 示例 2.1 : 以某xlsx文件为模板，生成表标题和表头，并在表格添加自定义信息，各行数据自动写入

#[derive(XlsxGroupWriteQuicker)]
#[xlsx_group_write(
    line_writer_simple = "line_index-1:number,&self.name,&self.tel,&self.dep",
    group_maker = "&self.dep",
    template_advance = "/home/feiy/Desktop/temp.xlsx,4",
    custom_info_adder = "Self::add_custom_info",
    output_file_name_simple = "/tmp/test",
    output_file_name_add_date = "true"
)]
struct MySimpleDataWithTemplate {
    pub name: String,
    pub tel: String,
    pub dep: String,
}
impl MySimpleDataWithTemplate {
    pub fn new(name: &str, tel: &str, dep: &str) -> Self {
        Self {
            name: name.into(),
            tel: tel.into(),
            dep: dep.into(),
        }
    }

    /// 对导出的xlsx文件进行一些个性化修改
    /// 比如需要在第二行插入对应分组名称，插入报表数据范围等信息
    ///
    /// 将在xlsx初始化完成后自动调用该方法
    ///
    /// # 参数说明
    ///
    /// * sheet 要修改的xlsx工作表
    /// * group_id 该xlsx对应的分组id
    fn add_custom_info(sheet: &mut Worksheet, group_id: &str) {
        sheet
            .get_cell_mut((&1, &2))
            .set_value_string(&format!("{group_id}，报表日期:2023年4月20日"));
    }
}

#[test]
fn test_simple_with_template() {
    // 初始化待导出数据
    let data = vec![
        MySimpleDataWithTemplate::new("张三", "185xxxx2228", "网金部"),
        MySimpleDataWithTemplate::new("李四", "185xxxx2229", "运管部"),
        MySimpleDataWithTemplate::new("王二", "185xxxx2230", "网金部"),
    ];
    // 导出数据到xlsx文件
    // 自动按照部门分别导出,同时还汇总导出一个汇总xlsx文件
    // 成功导出返回对应的文件信息和分组id
    let resp = MySimpleDataWithTemplate::write2xlsx_all(&data);
    println!("resp:{resp:#?}");
}

// # 示例 3 : 以动态使用某xlsx文件为模板，生成表标题和表头，并在表格添加自定义信息，各行数据自动写入

#[derive(XlsxGroupWriteQuicker)]
#[xlsx_group_write(
    line_writer_simple = "line_index-1:number,&self.name,&self.tel,&self.dep",
    group_maker = "&self.dep",
    template_getter = "Self::get_cur_template",
    custom_info_adder = "Self::add_custom_info",
    output_file_name_simple = "/tmp/test",
    output_file_name_add_date = "true"
)]
struct MySimpleDataWithTemplateGetter {
    pub name: String,
    pub tel: String,
    pub dep: String,
}
impl MySimpleDataWithTemplateGetter {
    pub fn new(name: &str, tel: &str, dep: &str) -> Self {
        Self {
            name: name.into(),
            tel: tel.into(),
            dep: dep.into(),
        }
    }
    /// 动态确定模板文件
    fn get_cur_template() -> XlsxInitTemplet {
        XlsxInitTemplet::new_advance("/home/feiy/Desktop/template.xlsx", 3)
    }
    /// 对导出的xlsx文件进行一些个性化修改
    /// 比如需要在第二行插入对应分组名称，插入报表数据范围等信息
    ///
    /// 将在xlsx初始化完成后自动调用该方法
    ///
    /// # 参数说明
    ///
    /// * sheet 要修改的xlsx工作表
    /// * group_id 该xlsx对应的分组id
    fn add_custom_info(sheet: &mut Worksheet, group_id: &str) {
        sheet
            .get_cell_mut((&1, &2))
            .set_value_string(&format!("{group_id}，报表日期:2023年4月20日"));
    }
}

#[test]
fn test_simple_with_template_getter() {
    // 初始化待导出数据
    let data = vec![
        MySimpleDataWithTemplateGetter::new("张三", "185xxxx2228", "网金部"),
        MySimpleDataWithTemplateGetter::new("李四", "185xxxx2229", "运管部"),
        MySimpleDataWithTemplateGetter::new("王二", "185xxxx2230", "网金部"),
    ];
    // 导出数据到xlsx文件
    // 自动按照部门分别导出,同时还汇总导出一个汇总xlsx文件
    // 成功导出返回对应的文件信息和分组id
    let resp = MySimpleDataWithTemplateGetter::write2xlsx_all(&data);
    println!("resp:{resp:#?}");
}

// # 示例 3 : 自动生成表头，各行数据调用个性化写入函数write_xlsx_line写入

#[derive(XlsxGroupWriteQuicker)]
#[xlsx_group_write(
    line_writer_advance = "Self::write_xlsx_line",
    group_maker = "&self.dep",
    template_simple = "序号,姓名,手机,部门",
    output_file_name_simple = "/tmp/test"
)]
struct MyAdvanceData {
    pub name: String,
    pub tel: String,
    pub dep: String,
}
impl MyAdvanceData {
    pub fn new(name: &str, tel: &str, dep: &str) -> Self {
        Self {
            name: name.into(),
            tel: tel.into(),
            dep: dep.into(),
        }
    }

    fn write_xlsx_line(
        line_data: &MyAdvanceData,
        sheet: &mut Worksheet,
        line_index: u32,
    ) -> Option<XlsxLineAdvanceWriterResult> {
        XlsxWriterTool::set_excel_cell_value_number(sheet, 1, line_index, line_index - 1);
        XlsxWriterTool::set_excel_cell_value_str(
            sheet,
            2,
            line_index,
            &format!("ad-{}", &line_data.name),
        );
        XlsxWriterTool::set_excel_cell_value_str(sheet, 3, line_index, &line_data.tel);
        XlsxWriterTool::set_excel_cell_value_str(sheet, 4, line_index, &line_data.dep);
        None
    }
}

#[test]
fn test_advance_write() {
    // 初始化待导出数据
    let data = vec![
        MyAdvanceData::new("张三", "185xxxx2228", "网金部"),
        MyAdvanceData::new("李四", "185xxxx2229", "运管部"),
        MyAdvanceData::new("王二", "185xxxx2230", "网金部"),
    ];
    // 导出数据到xlsx文件
    // 自动按照部门分别导出,同时还汇总导出一个汇总xlsx文件
    // 成功导出返回对应的文件信息和分组id
    let resp = MyAdvanceData::write2xlsx_all(&data);
    println!("resp:{resp:#?}");
}

// # 示例 4 : 自动生成表头，各行数据自动写入,输出文件名称通过函数获取

#[derive(XlsxGroupWriteQuicker)]
#[xlsx_group_write(
    line_writer_simple = "line_index-1:number,&self.name,&self.tel,&self.dep",
    group_maker = "&self.dep",
    template_simple = "序号,姓名,手机,部门",
    output_file_name_advance = "Self::get_output_file_name_advance"
)]
struct MyFileNameData {
    pub name: String,
    pub tel: String,
    pub dep: String,
}
impl MyFileNameData {
    pub fn new(name: &str, tel: &str, dep: &str) -> Self {
        Self {
            name: name.into(),
            tel: tel.into(),
            dep: dep.into(),
        }
    }

    /// 完全自定义的输出文件名称名称生成器
    ///
    /// 参数说明:
    ///
    /// * groupt_id ：当期数据的分组id
    #[allow(dead_code)]
    fn get_output_file_name_advance(group_id: &str) -> String {
        format!("/tmp/f-{group_id}.xlsx")
    }
}

#[test]
fn test_advance_file_name() {
    // 初始化待导出数据
    let data = vec![
        MyFileNameData::new("张三", "185xxxx2228", "网金部"),
        MyFileNameData::new("李四", "185xxxx2229", "运管部"),
        MyFileNameData::new("王二", "185xxxx2230", "网金部"),
    ];
    // 导出数据到xlsx文件
    // 自动按照部门分别导出,同时还汇总导出一个汇总xlsx文件
    // 成功导出返回对应的文件信息和分组id
    let resp = MyFileNameData::write2xlsx_all(&data);
    println!("resp:{resp:#?}");
}

// # 示例 5 : 自动生成表头，各行数据自动写入

#[derive(XlsxGroupWriteQuicker)]
#[xlsx_group_write(
    line_writer_simple = "line_index-1:number,&self.name,&self.tel,&self.dep",
    group_maker = "&self.dep",
    template_simple = "序号,姓名,手机,部门",
    output_file_name_simple = "/tmp/test"
)]
struct MyStrData<'a> {
    pub name: &'a str,
    pub tel: &'a str,
    pub dep: &'a str,
}
impl<'a> MyStrData<'a> {
    pub fn new(name: &'a str, tel: &'a str, dep: &'a str) -> Self {
        Self { name, tel, dep }
    }
}

#[test]
fn test_str_data() {
    // 初始化待导出数据
    let data = vec![
        MyStrData::new("张三", "185xxxx2228", "网金部"),
        MyStrData::new("李四", "185xxxx2229", "运管部"),
        MyStrData::new("王二", "185xxxx2230", "网金部"),
    ];
    // 导出数据到xlsx文件
    // 自动按照部门分别导出,同时还汇总导出一个汇总xlsx文件
    // 成功导出返回对应的文件信息和分组id
    let resp = MyStrData::write2xlsx_all(&data);
    println!("resp:{resp:#?}");
}

// # 示例 7 : 自动生成表头，各行数据自动写入，传递额外参数到文件名称，写入个性化信息到xlsx表中

#[derive(XlsxGroupWriteQuicker)]
#[xlsx_group_write(
    line_writer_advance_with_extra_arg = "Self::write_xlsx_line",
    group_maker = "&self.dep",
    template_getter = "Self::get_cur_template",
    extra_arg_type = "String",
    custom_info_adder = "Self::add_custom_info",
    output_file_name_advance = "Self::get_output_file_name_advance"
)]
struct MySimpleDataWithExtraArg {
    pub name: String,
    pub tel: String,
    pub dep: String,
}
impl MySimpleDataWithExtraArg {
    pub fn new(name: &str, tel: &str, dep: &str) -> Self {
        Self {
            name: name.into(),
            tel: tel.into(),
            dep: dep.into(),
        }
    }
    /// 写入行数据，传入额外参数
    fn write_xlsx_line(
        line_data: &MySimpleDataWithExtraArg,
        sheet: &mut Worksheet,
        line_index: u32,
        extra_arg: Option<&String>,
    ) -> Option<XlsxLineAdvanceWriterResult> {
        XlsxWriterTool::set_excel_cell_value_number(sheet, 1, line_index, line_index - 1);
        XlsxWriterTool::set_excel_cell_value_str(
            sheet,
            2,
            line_index,
            &format!("ad-{}", &line_data.name),
        );
        XlsxWriterTool::set_excel_cell_value_str(sheet, 3, line_index, &line_data.tel);
        XlsxWriterTool::set_excel_cell_value_str(sheet, 4, line_index, &line_data.dep);
        if let Some(extra_arg) = extra_arg {
            XlsxWriterTool::set_excel_cell_value_str(sheet, 5, line_index, extra_arg);
        }
        None
    }

    /// 动态确定模板文件
    fn get_cur_template() -> XlsxInitTemplet {
        XlsxInitTemplet::new_advance("/home/feiy/Desktop/template.xlsx", 3)
    }
    /// 对导出的xlsx文件进行一些个性化修改
    /// 比如需要在第二行插入对应分组名称，插入报表数据范围等信息
    ///
    /// 将在xlsx初始化完成后自动调用该方法
    ///
    /// # 参数说明
    ///
    /// * sheet 要修改的xlsx工作表
    /// * group_id 该xlsx对应的分组id
    fn add_custom_info(sheet: &mut Worksheet, group_id: &str, org_name: Option<&String>) {
        if let Some(org_name) = org_name {
            sheet
                .get_cell_mut((&1, &5))
                .set_value_string(&format!("{org_name} {group_id}，报表日期:2023年4月20日"));
        } else {
            sheet
                .get_cell_mut((&1, &5))
                .set_value_string(&format!("{group_id}，报表日期:2023年4月20日"));
        }
    }
    /// 完全自定义的输出文件名称名称生成器
    ///
    /// 参数说明:
    ///
    /// * groupt_id ：当期数据的分组id
    #[allow(dead_code)]
    fn get_output_file_name_advance(group_id: &str, org_name: Option<&String>) -> String {
        if let Some(org_name) = org_name {
            format!("/tmp/f-{org_name}-{group_id}.xlsx")
        } else {
            format!("/tmp/f-{group_id}.xlsx")
        }
    }
}

#[test]
fn test_simple_with_extra_arg() {
    // 初始化待导出数据
    let data = vec![
        MySimpleDataWithExtraArg::new("张三", "185xxxx2228", "网金部"),
        MySimpleDataWithExtraArg::new("李四", "185xxxx2229", "运管部"),
        MySimpleDataWithExtraArg::new("王二", "185xxxx2230", "网金部"),
    ];
    // 导出汇总数据到xlsx文件
    // 成功导出返回对应的文件信息和分组id
    // 传入个性化参数
    let resp = MySimpleDataWithExtraArg::write2xlsx_merge_only_with_extra_arg(
        &data,
        Some(String::from("个性化参数")),
    );
    println!("resp:{resp:#?}");
}
